package cn.edu.buaa.treehole.service;

import cn.edu.buaa.treehole.config.Setting;
import cn.edu.buaa.treehole.dao.ReplyDao;
import cn.edu.buaa.treehole.dao.exception.DaoException;
import cn.edu.buaa.treehole.dao.exception.PidNotExistException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;

@Service
public class ReplyListService {
    private final ReplyDao replyDao;
    private Setting setting;

    @Autowired
    public ReplyListService(ReplyDao replyDao) {
        this.replyDao = replyDao;
    }

    public Setting getSetting() {
        return setting;
    }

    @Autowired
    public void setSetting(Setting setting) {
        this.setting = setting;
    }

    private final HashMap<Long, HashSet<Long>> cache = new HashMap<>();

    public long getEarliestReply(long pid) throws PidNotExistException, DaoException {
        return replyDao.getEarliestReplyRid(pid);
    }

    public long getLatestReply(long pid) throws PidNotExistException, DaoException {
        return replyDao.getLatestReplyRid(pid);
    }

    public boolean contain(long pid, long rid) throws DaoException {
        if (!setting.blockListCache() && cache.containsKey(pid)) {
            return cache.get(pid).contains(rid);
        }
        return replyDao.contain(pid, rid);
    }

    public boolean isCachedAllRepliesForPost(long pid) {
        return !setting.blockInfoCache() && cache.containsKey(pid);
    }

    public void createEmptyCacheForPost(long pid) {
        if (setting.blockListCache() || cache.containsKey(pid)) {
            return;
        }
        HashSet<Long> rids = new HashSet<>();
        cache.put(pid, rids);
    }

    public void cacheAllRepliesForPostFromDatabase(long pid) throws DaoException {
        if (setting.blockListCache() || cache.containsKey(pid)) {
            return;
        }
        HashSet<Long> rids = new HashSet<>();
        cache.put(pid, rids);
        try {
            long latestRid = replyDao.getLatestReplyRid(pid);
            long earliestRid = replyDao.getEarliestReplyRid(pid);
            for (long rid = earliestRid; rid <= latestRid; rid++) {
                if (replyDao.contain(pid, rid)) {
                    rids.add(rid);
                }
            }
        } catch (PidNotExistException ignored) { }
    }

    public void addReplyCache(long pid, long rid) {
        if (setting.blockListCache() || cache.containsKey(pid)) {
            cache.get(pid).add(rid);
        }
    }

    public void deleteReplyCache(long pid, long rid) {
        if (setting.blockListCache() || cache.containsKey(pid)) {
            cache.get(pid).remove(rid);
        }
    }

    public void deleteAllRepliesForPost(long pid) {
        if (setting.blockListCache()) {
            return;
        }
        cache.remove(pid);
    }
}
